﻿<Assembly: System.Windows.Markup.XmlnsDefinition("http://wpfglue.wordpress.com/localization", "WPFGlue.Localization")> 
<Assembly: System.Windows.Markup.XmlnsPrefix("http://wpfglue.wordpress.com/localization", "l")> 
Namespace Localization
    Public Class Localization

#Region "Switching the Keyboard Language"
        Public Shared ReadOnly KeyboardLanguageProperty As DependencyProperty = DependencyProperty.RegisterAttached("KeyboardLanguage", GetType(String), GetType(Localization), New FrameworkPropertyMetadata(Nothing, System.Windows.FrameworkPropertyMetadataOptions.Inherits, AddressOf OnKeyboardLanguageChanged))
        Public Shared Function GetKeyboardLanguage(ByVal d As DependencyObject) As String
            Return d.GetValue(KeyboardLanguageProperty)
        End Function
        Public Shared Sub SetKeyboardLanguage(ByVal d As DependencyObject, ByVal value As String)
            d.SetValue(KeyboardLanguageProperty, value)
        End Sub
        Public Shared Sub OnKeyboardLanguageChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
            If TypeOf d Is FrameworkElement Then
                Dim l As System.Globalization.CultureInfo = FindKeyboardLanguage(e.NewValue)
                If String.IsNullOrEmpty(e.NewValue) Or l Is System.Globalization.CultureInfo.InvariantCulture Then
                    d.ClearValue(InputLanguageManager.InputLanguageProperty)
                    d.ClearValue(InputLanguageManager.RestoreInputLanguageProperty)
                Else
                    d.SetValue(InputLanguageManager.InputLanguageProperty, l)
                    d.SetValue(InputLanguageManager.RestoreInputLanguageProperty, True)
                    InputLanguageManager.Current.CurrentInputLanguage = l
                End If
            End If
        End Sub

        Public Shared Function FindKeyboardLanguage(ByVal tag As String) As System.Globalization.CultureInfo
            Dim result As System.Globalization.CultureInfo = System.Globalization.CultureInfo.InvariantCulture
            If Not String.IsNullOrEmpty(tag) Then
                For Each c As System.Globalization.CultureInfo In InputLanguageManager.Current.AvailableInputLanguages
                    If c.IetfLanguageTag.ToUpper.StartsWith(tag.ToUpper) Then
                        result = c
                    End If
                    If c.IetfLanguageTag.ToUpper = tag.ToUpper Then
                        Exit For
                    End If
                Next
            End If
            Return result
        End Function

        Public Shared ReadOnly TracksKeyboardLanguageProperty As DependencyProperty = DependencyProperty.RegisterAttached("TracksKeyboardLanguage", GetType(Boolean), GetType(Localization), New PropertyMetadata(AddressOf OnTracksKeyboardLanguageChanged))
        Public Shared Function GetTracksKeyboardLanguage(ByVal d As DependencyObject) As Boolean
            Return d.GetValue(TracksKeyboardLanguageProperty)
        End Function
        Public Shared Sub SetTracksKeyboardLanguage(ByVal d As DependencyObject, ByVal value As Boolean)
            d.SetValue(TracksKeyboardLanguageProperty, value)
        End Sub
        Private Shared Sub OnTracksKeyboardLanguageChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
            If TypeOf d Is RichTextBox Then
                Dim b As RichTextBox = d
                If CBool(e.OldValue) Then
                    RemoveHandler b.SelectionChanged, AddressOf OnSelectionChanged
                End If
                If CBool(e.NewValue) Then
                    AddHandler b.SelectionChanged, AddressOf OnSelectionChanged
                End If
            End If
        End Sub

        Private Shared Sub OnSelectionChanged(ByVal sender As Object, ByVal e As RoutedEventArgs)
            Dim b As RichTextBox = sender
            Dim f As FrameworkContentElement = TryCast(b.Selection.Start.Parent, FrameworkContentElement)
            If f IsNot Nothing Then
                Dim tag As String = GetKeyboardLanguage(f)
                If Not String.IsNullOrEmpty(tag) Then
                    If Not InputLanguageManager.Current.CurrentInputLanguage.IetfLanguageTag.ToUpper.StartsWith(tag.ToUpper) Then
                        InputLanguageManager.Current.CurrentInputLanguage = FindKeyboardLanguage(tag)
                    End If
                End If
            End If
            e.Handled = False
        End Sub
#End Region

#Region "Selecting the UI Language"
        Public Shared ReadOnly UILanguageProperty As DependencyProperty = DependencyProperty.RegisterAttached("UILanguage", GetType(String), GetType(Localization), New PropertyMetadata(Nothing, AddressOf OnUILanguageChanged, AddressOf CoerceUILanguage))
        Public Shared Function GetUILanguage(ByVal d As DependencyObject) As String
            Return d.GetValue(UILanguageProperty)
        End Function
        Public Shared Sub SetUILanguage(ByVal d As DependencyObject, ByVal value As String)
            d.SetValue(UILanguageProperty, value)
        End Sub
        Private Shared Sub OnUILanguageChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
            If e.NewValue IsNot Nothing Then
                System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo(CStr(e.NewValue))
            End If
        End Sub
        Private Shared Function CoerceUILanguage(ByVal d As DependencyObject, ByVal baseValue As Object) As Object
            Dim result As String = baseValue
            If baseValue Is Nothing Then
                result = System.Globalization.CultureInfo.CurrentUICulture.IetfLanguageTag
            End If
            Return result
        End Function


        Public Shared Sub SyncFlowDirection(ByVal d As DependencyObject)
            If System.Threading.Thread.CurrentThread.CurrentUICulture.TextInfo.IsRightToLeft Then
                d.SetValue(FrameworkElement.FlowDirectionProperty, FlowDirection.RightToLeft)
            Else
                d.SetValue(FrameworkElement.FlowDirectionProperty, FlowDirection.LeftToRight)
            End If
        End Sub

        Public Shared Sub SyncLanguage(ByVal d As DependencyObject)
            Dim lang As System.Windows.Markup.XmlLanguage = System.Windows.Markup.XmlLanguage.GetLanguage(System.Globalization.CultureInfo.CurrentUICulture.IetfLanguageTag)
            d.SetValue(FrameworkElement.LanguageProperty, lang)
        End Sub
#End Region

#Region "Selecting Resource Providers"
        Public Shared ReadOnly ResourceReferenceTypeProperty As DependencyProperty = DependencyProperty.RegisterAttached("ResourceReferenceType", GetType(Type), GetType(Localization), New PropertyMetadata(AddressOf OnResourceReferenceTypeChanged))
        Public Shared Function GetResourceReferenceType(ByVal d As DependencyObject) As Type
            Return d.GetValue(ResourceReferenceTypeProperty)
        End Function
        Public Shared Sub SetResourceReferenceType(ByVal d As DependencyObject, ByVal value As Type)
            d.SetValue(ResourceReferenceTypeProperty, value)
        End Sub
        Private Shared Sub OnResourceReferenceTypeChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
            If e.NewValue Is Nothing Then
                Dim t As Type = Application.Current.GetType
                ResourceExtension.Assembly = t.Assembly
                ResourceExtension.BaseName = t.Namespace & ".Resources"
            Else
                Dim t As Type = e.NewValue
                ResourceExtension.Assembly = t.Assembly
                ResourceExtension.BaseName = t.Namespace & ".Resources"
            End If
        End Sub

        Public Shared ReadOnly ResourceBasenameProperty As DependencyProperty = DependencyProperty.RegisterAttached("ResourceBasename", GetType(String), GetType(Localization), New PropertyMetadata(AddressOf OnResourceBasenameChanged))
        Public Shared Function GetResourceBasename(ByVal d As DependencyObject) As String
            Return d.GetValue(ResourceBasenameProperty)
        End Function
        Public Shared Sub SetResourceBasename(ByVal d As DependencyObject, ByVal value As String)
            d.SetValue(ResourceBasenameProperty, value)
        End Sub
        Private Shared Sub OnResourceBasenameChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
            If e.NewValue Is Nothing Then
                ResourceExtension.BaseName = Application.Current.GetType.Namespace & ".Resources"
            Else
                ResourceExtension.BaseName = e.NewValue
            End If
        End Sub


        Public Shared ReadOnly ResourceAssemblyProperty As DependencyProperty = DependencyProperty.RegisterAttached("ResourceAssembly", GetType(System.Reflection.Assembly), GetType(Localization), New PropertyMetadata(AddressOf OnResourceAssemblyChanged))
        Public Shared Function GetResourceAssembly(ByVal d As DependencyObject) As System.Reflection.Assembly
            Return d.GetValue(ResourceAssemblyProperty)
        End Function
        Public Shared Sub SetResourceAssembly(ByVal d As DependencyObject, ByVal value As System.Reflection.Assembly)
            d.SetValue(ResourceAssemblyProperty, value)
        End Sub
        Private Shared Sub OnResourceAssemblyChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
            If e.NewValue Is Nothing Then
                ResourceExtension.Assembly = Application.Current.GetType.Assembly
            Else
                ResourceExtension.Assembly = e.NewValue
            End If
        End Sub
#End Region

    End Class
End Namespace
